//******************************************************************/
//版本说明:
//V0.1		2017-03-30	11:00	yshao	复制自SL909_G01_X32
//V2.1		2019-01-31	11:00	yshao	调整init_end和comm_en,init_mode
//******************************************************************/
//******************************************************************/
//			   全局参数定义
//******************************************************************/
//仿真模式
//`define	SIMULATION	1
//`timescale	1ps/1ps

//FPGA程序模式
`define		APP_MODE	1
//`define	TEST_MODE	2
//`define	BOOT_MODE	3

//******************************************************************/
//			   FPGA顶层
//******************************************************************/
module AH901_G01(
		input	wire		sclkin,
		input	wire		key_in,
		input	wire		s_pullup,
		
		output	wire		sa_clk,
		output	wire	[2:0]	sa_cnt,
		output	wire		sa_dqm_l,
		output	wire		sa_dqm_h,
		output	wire	[10:0]	sa_addr,
		output	wire	[1:0]	sa_bank,
		inout	tri	[31:0]	sa_data,

		input	wire		mcu_dmx_tx,		//uart2_sync,
		output	wire		mcu_dmx_rx,		//uart3_sync,

		input	wire		mcu_fpga_ctrl,		//mcu到fpga的模式控制信号

		input	wire		mcu_spi_fpga,		//spi工作在通讯模式
		input	wire		mcu_spi_clk,
		input	wire		mcu_spi_mosi,
		output	wire		mcu_spi_miso,

		output	wire		spi2_cs,
		output	wire		spi2_clk,
		output	wire		spi2_mosi,
								
		output	wire		sd_clk,
		inout	tri		sd_cmd_sdi,
		input	wire		sd_dat0_sdo,
		input	wire		sd_dat1,
		input	wire		sd_dat2,
		inout	wire		sd_dat3_cs,
		input	wire		sd_cd,
		input	wire		sd_wp,

		output	wire		phy_rst,
		output	wire		phy_mdc,
		inout	tri		phy_mdio,

		input	wire		gp0_rxc,
		input	wire		gp0_rxdv,
		input	wire	[3:0]	gp0_rxd,
		output	wire		gp0_txc,
		output	wire		gp0_txen,
		output	wire	[3:0]	gp0_txd,
		
		input	wire		gp1_rxc,
		input	wire		gp1_rxdv,
		input	wire	[3:0]	gp1_rxd,
		output	wire		gp1_txc,
		output	wire		gp1_txen,
		output	wire	[3:0]	gp1_txd,

		output	wire	[7:0]	port_da,
		output	wire	[7:0]	port_le,
		input	wire	[7:0]	port_ex,
		
		output	wire	[3:0]	port_ain
		);

//****************************************************************
//		内部信号
//****************************************************************
wire		resetb, oclk, sclk;
wire	[20:0]	time_us, sync_us;

//PHY设置总线相关信号
wire		init_mode, set_d_ok, ext_d_ok;
wire	[31:0]	set_addr;
wire	[7:0]	set_data, rd_data;

//MCU设置总线相关信号
wire		mcu_set_d_ok, mcu_ext_d_ok;
wire	[31:0]	mcu_set_addr;
wire	[7:0]	mcu_set_data, mcu_rd_data;
wire	[7:0]	mcu_rd_hub;


//显示数据相关
reg		vs, ds, h_start;
reg	[7:0]	data;
reg	[10:0]	h_num;

wire		input_L9, input_artnet;
wire		vs_a, ds_a, h_start_a, vs_sd, ds_sd, h_start_sd;
wire	[7:0]	data_a, data_sd;
wire	[10:0]	h_num_a, h_num_sd;

wire		l2048_mode, artnet_mode;

wire	[15:0]	state;
wire	[1:0]	color_restore_type;
wire	[7:0]	testmode;
wire	[8:0]	cascade_light;

wire		black;

reg	[5:0]	count_34ms;
reg		vs_34ms;

//输出模块接口信号
wire		vs_out;
wire		disp_read_req;
wire	[23:0]	disp_read_addr;
wire	[3:0]	disp_read_cnt;
wire		disp_read_ack;
wire	[31:0]	disp_read_data;
wire	[11:0]	d_addr;
wire	[2:0]	p_addr;

//输出控制信号
wire		out_sync;
wire 	[7:0]	out_data;
wire 	[7:0]	out_data_n;
wire		clk_out;
wire		clk_out_n;

//DMX输出信号
wire	[1:0]	dmx_mode;
wire		dmx_send_flag;
wire	[7:0]	out_data_dmx;

//SD播放信号
wire		sd_play_en, mcu_play_en, mcu_config_en, force_dis_en, force_send_play;

wire		sd_valid, sd_play_clk, sd_play_cmd_out, sd_play_cmd_oe;
wire	[3:0]	sd_play_data, sd_dat_mcu;
reg	[3:0]	sd_dat_dis;

wire		f_start, f_work, v_work, sd_play_flag;
wire	[40:0]	f_addr;
wire	[23:0]	f_size;
wire	[12:0]	l_size;

reg		local_dis_flag, mcu_play_flag;

//反馈网口信号
wire		send_flag_dis, pre_flag_dis;
wire	[7:0]	send_data_dis, sd_tout, hub_tout;

//**********调试用信号**********
wire	[31:0]	a1_tout, out_tout, sa_tout, sd_f_tout;

//**********转发用信号**********
wire		rx_clk, rx_dv, tx_en;
wire		dis_flag, cmd_flag, rec_flag;
wire	[1:0]	rx_type, tx_ck;
wire	[7:0]	rx_data, rec_data, tx_data;

wire		send_req_c, send_req_v, send_flag_c, send_flag_v;
wire		send_ack_c, send_ack_v;
wire	[7:0]	send_data_c, send_data_v;

wire		send_sync;
reg		send_flag;
reg	[7:0]	send_data;
reg	[2:0]	send_state;

wire		read_req, sd_rd_en, read_ok;
reg	[11:0]	d_max;
wire	[12:0]	h_size, h_offset;
wire	[9:0]	p_max, read_h_num;
wire	[31:0]	sd_rd_data;

//******************************************************************/
//			   参数定义
//******************************************************************/
//程序版本信息
parameter	MAIN_FUNCTION	=  "A";		//ASCII "S"  
parameter	SUB_FUNCTION	=  "H";		//ASCII "L"  
parameter	MAIN_SOLUTION	=  9;		//"9"        
parameter	SUB_SOLUTION	=  1;		//"09"       
parameter	APPLICATION_TYPE=  "G";		//ASCII "G"  
parameter	MAIN_VERSION	=  8'd1;	//"03"       
parameter	SUB_VERSION	=  8'd1;	//"X01"
parameter	MINI_VERSION	=  8'd8;	//" "  

//模块参数设置
defparam	comm_top.phy_comm.state_ctrl.main_function	=MAIN_FUNCTION;
defparam	comm_top.phy_comm.state_ctrl.sub_function	=SUB_FUNCTION;
defparam	comm_top.phy_comm.state_ctrl.main_solution	=MAIN_SOLUTION;
defparam	comm_top.phy_comm.state_ctrl.sub_solution	=SUB_SOLUTION;
defparam	comm_top.phy_comm.state_ctrl.application_type	=APPLICATION_TYPE;
defparam	comm_top.phy_comm.state_ctrl.main_version	=MAIN_VERSION;
defparam	comm_top.phy_comm.state_ctrl.sub_version	=SUB_VERSION;
defparam	comm_top.phy_comm.state_ctrl.mini_version	=MINI_VERSION;

defparam        comm_top.mcu_comm.main_function		=	MAIN_FUNCTION;
defparam        comm_top.mcu_comm.sub_function		=	SUB_FUNCTION;
defparam        comm_top.mcu_comm.main_solution		=	MAIN_SOLUTION;
defparam        comm_top.mcu_comm.sub_solution		=	SUB_SOLUTION;
defparam        comm_top.mcu_comm.application_type	=	APPLICATION_TYPE;
defparam        comm_top.mcu_comm.main_version		=	MAIN_VERSION;
defparam        comm_top.mcu_comm.sub_version		=	SUB_VERSION;
defparam        comm_top.mcu_comm.mini_version		=	MINI_VERSION;

//状态机
parameter	SSS_IDLE	=  3'b001;
parameter	SSS_COM		=  3'b010;
parameter	SSS_DIS		=  3'b100;

//**************************************************************
//			通讯模块
//**************************************************************
a1_comm_top comm_top(
		//时钟，按键，Led
		.sclkin(sclkin),
		.key_in(key_in),
		.led_g(),

		//输出复位和时钟
		.resetb(resetb),
		.sclk(sclk),
		.oclk(oclk),
		.sa_clk(sa_clk),
		.clk_25M(clk_25M),

		//MCU通讯接口
		.mcu_fpga_ctrl(mcu_fpga_ctrl),
		
		.mcu_spi_fpga(mcu_spi_fpga),
		.mcu_spi_clk(mcu_spi_clk),
		.mcu_spi_mosi(mcu_spi_mosi),
		.mcu_spi_miso(mcu_spi_miso),

		.spi2_cs(spi2_cs),
		.spi2_clk(spi2_clk),
		.spi2_mosi(spi2_mosi),

		.gp0_rxc(gp0_rxc),
		.gp0_rxdv(gp0_rxdv),
		.gp0_rxd(gp0_rxd),
		.gp0_txc(gp0_txc),
		.gp0_txen(gp0_txen),
		.gp0_txd(gp0_txd),

		.gp1_rxc(gp1_rxc),
		.gp1_rxdv(gp1_rxdv),
		.gp1_rxd(gp1_rxd),
		.gp1_txc(gp1_txc),
		.gp1_txen(gp1_txen),
		.gp1_txd(gp1_txd),

		//PORTA转发接收
		.rx_clk(rx_clk),
		.rx_dv(rx_dv),
		.rx_data(rx_data),
		.rx_type(rx_type),
		
		//PORTB转发发送
		.tx_ck(tx_ck),
		.tx_en(tx_en),
		.tx_data(tx_data),

		//SD卡通讯接口
		.sd_clk(sd_clk),
		.sd_cmd_sdi(sd_cmd_sdi),
		.sd_dat0_sdo(sd_dat0_sdo),
		.sd_dat1(sd_dat1),
		.sd_dat2(sd_dat2),
		.sd_dat3_cs(sd_dat3_cs),
		.sd_cd(sd_cd),
		.sd_wp(sd_wp),

		//分频时钟
		.time_us(time_us),
		.sync_us(sync_us),

		//MCU总线接口
		.mcu_set_d_ok(mcu_set_d_ok),
		.mcu_ext_d_ok(mcu_ext_d_ok),
		.mcu_set_addr(mcu_set_addr),
		.mcu_set_data(mcu_set_data),
		.mcu_rd_data(mcu_rd_data),

		//PHY总线接口
		.init_mode(init_mode),
		.set_d_ok(set_d_ok),
		.ext_d_ok(ext_d_ok),
		.set_addr(set_addr),
		.set_data(set_data),
		.rd_data(rd_data),

		//显示数据接口
		.vs(vs_a),
		.ds(ds_a),
		.data(data_a),
		.h_start(h_start_a),
		.h_num(h_num_a),
		.l2048_mode(l2048_mode),
		.artnet_mode(artnet_mode),
		.h_offset(h_offset),
		.h_total(h_size),
		.l_total(p_max),

		.state(),
		.color_restore_type(),
		.testmode(),
		.cascade_light(),

		.black(),

		//背板控制接口
		.fpga_dmx_send(0),
		.mcu_dmx_ten(),
		
		//SD卡播放指示
		.input_L9(),
		.input_artnet(),
		.sd_valid(),
		.sd_play_flag(0),
		.local_dis_flag(0),

		//SD卡播放操作接口
		.sd_play_clk(0),
		.sd_play_cmd_out(0),
		.sd_play_cmd_oe(0),
		.sd_play_data(),
		//SD发送数据包接口
		.force_send_play(),
		.send_flag_dis(0),
		.pre_flag_dis(0),
		.send_data_dis(0),

		//调试接口
		.tout(a1_tout)   
		);

//**************************************************************
//			转发处理
//**************************************************************
//PORTA控制模块
cascade_rec cascade_rec(
		.resetb(resetb),
		.sclk(sclk),

		.rx_clk(rx_clk),
		.rx_dv(rx_dv),
		.rgmii_rx_data(rx_data),
		.rx_type(rx_type),
		
		.p_size(),
		
		.vs_flag(vs_flag),
		.cmd_flag(cmd_flag),
		.dis_flag(dis_flag),
		
		.rec_flag(rec_flag),
		.rec_data(rec_data),
		
		.tout()
		);
		
cmd_send cmd_send(
		.resetb(resetb),
		.sclk(sclk),
		
		.cmd_flag(cmd_flag),
		.rec_flag(rec_flag),
		.rec_data(rec_data),
		
		.send_req(send_req_c),
		.send_ack(send_ack_c),
		
		.send_sync(send_sync),
		.send_flag(send_flag_c),
		.send_data(send_data_c),
		
		.tout()
		);

//************************************************************/
//		SDRAM接口
//************************************************************/
L9_sdram_top_02 sdram_top(
		//复位和时钟
		.resetb(resetb),
		.sclk(sclk),
		.sync_16us(sync_us[4]),
		.init_mode(init_mode),
	
		//写显示数据接口
		.vsin(vs_a),
		.dsin(ds_a),
		.din(data_a),
		.h_start(h_start_a),
		.h_num(h_num_a),
		.l2048_mode(0),
		.artnet_mode(0),
        
		.vs_out(vs_a),
		.state(0),

		//显示数据读接口
		.p_max(p_max),
		.read_req(read_req),
		.read_h_num(read_h_num),
		.sd_rd_en(sd_rd_en),
		.read_ok(read_ok),
		.sd_rd_data(sd_rd_data),

		//sdram接口
	        .sa_clk(),
	        .sa_cnt(sa_cnt),
	        .sa_addr(sa_addr),
	        .sa_bank(sa_bank),
	        .sa_data(sa_data),
	        
	        .tout(sa_tout)
        	);

assign sa_dqm_l = 0;
assign sa_dqm_h = 0;

//************************************************************/
//		帧输出
//************************************************************/
//assign	h_size = 32;
//assign	p_max = 256;

always @(posedge sclk)
	d_max <= {p_max, 1'b0} + p_max;

v_frame_gen f_g(
		.resetb(resetb),
		.sclk(sclk),

		.h_offset(h_offset),
		.h_size(h_size),
		.d_max(d_max),
	        
		.cmd_d_ok(0),
		.cmd_addr(0),
		.cmd_data(0),
	        
		.vs_flag(vs_flag),

		.read_req(read_req),
		.read_h_num(read_h_num),
		.sd_rd_en(sd_rd_en),
		.read_ok(read_ok),
		.sd_rd_data(sd_rd_data),
	        
		.send_req(send_req_v),
		.send_ack(send_ack_v),

		.send_sync(send_sync),
		.send_flag(send_flag_v),
		.send_data(send_data_v),

		.tout()
		);

//************************************************************/
//		输出选通
//************************************************************/
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		send_state <= SSS_IDLE;
	else 
		case(send_state)
			SSS_IDLE:
				if (send_req_c == 1)
					send_state <= SSS_COM;
				else if (send_req_v == 1)
					send_state <= SSS_DIS;
			SSS_COM:
				if (send_req_c == 0)
					send_state <= SSS_IDLE;
			SSS_DIS:
				if (send_req_v == 0)
					send_state <= SSS_IDLE;
			default:
				send_state <= SSS_IDLE;
		endcase

assign	send_ack_c = send_state[1];
assign	send_ack_v = send_state[2];

always @(posedge sclk)
	if (send_state == SSS_COM) begin
		send_flag <= send_flag_c;
		send_data <= send_data_c;
	end
	else if (send_state == SSS_DIS) begin
		send_flag <= send_flag_v;
		send_data <= send_data_v;
	end
	else begin
		send_flag <= 0;
		send_data <= 0;
	end

mii_send mii_send(
		.resetb(resetb),
		.sclk(sclk),
		
		.send_sync(send_sync),

		.send_flag(send_flag),
		.send_data(send_data),
		
		.tx_ck(tx_ck),
		.tx_en(tx_en),
		.tx_data(tx_data),

		.tout()
		);

//************************************************************/
//		背板接口
//************************************************************/
//输出给背板的信号
assign  port_da = 0;  
assign  port_le = 8'hFF;  
//assign  port_da = {tx_ck, tx_en, tx_data[3:0]};  
//assign  port_le = {ds_a, vs_a, dis_flag, vs_flag, rec_flag};  

//************************************************************/
//		调试接口
//************************************************************/                    
assign	port_ain[0] = spi2_cs;
assign	port_ain[1] = spi2_clk;
assign	port_ain[2] = spi2_mosi;
assign	port_ain[3] = mcu_spi_fpga;

//assign	port_ain[0] = phy_rst;
//assign	port_ain[1] = phy_mdc;
//assign	port_ain[2] = phy_mdio;
//assign	port_ain[3] = mcu_spi_fpga;


//assign	JP202_PIN3 = mcu_spi_fpga;
//assign	JP202_PIN4 = time_us[14];
//assign	JP202_PIN5 = a1_tout[0];

endmodule
